namespace Framework
{
    public class FlexBuffer
    {
        public int RiseValue;
        public int Length { get; private set; }
        public int Offset { get; private set; }
        public byte[] Buffer { get; private set; }
        public FlexBuffer(int capacity)
        {
            Length = 0;
            Offset = 0;
            if (capacity < 2)
            {
                capacity = 2;
            }
            Buffer = new byte[capacity];
        }
        public void Clear()
        {
            Length = 0;
            Offset = 0;
        }
        private void SetSize(int value)
        {
            var len = value - Buffer.Length;
            if (len > 0)
            {
                if (RiseValue < 0)
                {
                    RiseValue = 0;
                }
                byte[] array = new byte[value + RiseValue];
                System.Buffer.BlockCopy(Buffer, 0, array, 0, Buffer.Length);
                this.Buffer = array;
            }
        }
        private byte[] _swapBuffer;
        public bool Write(byte[] src, int length)
        {
            if (length < 1 || length > src.Length)
            {
                return false;
            }
            var newSize = Offset + Length + length;
            if (newSize > Buffer.Length)
            {
                //扩容
                if (Length <= Offset)
                {
                    //移动位置
                    if (_swapBuffer == null || _swapBuffer.Length < newSize)
                    {
                        _swapBuffer = new byte[newSize];
                    }
                    System.Buffer.BlockCopy(Buffer, Offset, _swapBuffer, 0, Buffer.Length);
                    System.Buffer.BlockCopy(_swapBuffer, 0, Buffer, 0, Length);
                    Offset = 0;
                    newSize = Length + length;
                }

                if (newSize > Buffer.Length)
                {
                    SetSize(newSize);
                }
            }
            System.Buffer.BlockCopy(src, 0, Buffer, Offset + Length, length);
            Length += length;
            return true;
        }
        public bool Read(byte[] dst, int length)
        {
            if (this.Length < 1)
            {
                return false;
            }
            if (length < 1)
            {
                return false;
            }
            if (length > dst.Length)
            {
                return false;
            }
            if (Offset + this.Length > Buffer.Length)
            {
                return false;
            }
            System.Buffer.BlockCopy(Buffer, Offset, dst, 0, length);
            return true;
        }
        public bool Delete(int length)
        {
            if (length < 1) return false;
            if (length > Length)
            {
                return false;
            }
            Length -= length;
            Offset += length;
            return true;
        }
    }
}